package org.budo.mongo.wrapper;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.budo.mongo.filter.MongoFilter;
import org.budo.mongo.filter.MongoFilterChain;
import org.budo.mongo.filter.MongoFilterChainImpl;

import com.mongodb.AggregationOptions;
import com.mongodb.AggregationOutput;
import com.mongodb.BulkWriteOperation;
import com.mongodb.CommandResult;
import com.mongodb.Cursor;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBDecoderFactory;
import com.mongodb.DBEncoder;
import com.mongodb.DBEncoderFactory;
import com.mongodb.DBObject;
import com.mongodb.GroupCommand;
import com.mongodb.InsertOptions;
import com.mongodb.MapReduceCommand;
import com.mongodb.MapReduceCommand.OutputType;
import com.mongodb.MapReduceOutput;
import com.mongodb.ParallelScanOptions;
import com.mongodb.ReadConcern;
import com.mongodb.ReadPreference;
import com.mongodb.WriteConcern;
import com.mongodb.WriteResult;
import com.mongodb.client.model.DBCollectionCountOptions;
import com.mongodb.client.model.DBCollectionDistinctOptions;
import com.mongodb.client.model.DBCollectionFindAndModifyOptions;
import com.mongodb.client.model.DBCollectionFindOptions;
import com.mongodb.client.model.DBCollectionRemoveOptions;
import com.mongodb.client.model.DBCollectionUpdateOptions;

@SuppressWarnings({ "rawtypes", "unchecked" })
public class DBCollectionWrapper extends DBCollection {
    private DBCollection dbCollection;

    private MongoFilterChain filterChain;

    public DBCollectionWrapper(List<MongoFilter> filters, DBCollection dbCollection, DB db, String name) {
        super(db, name);
        this.filterChain = new MongoFilterChainImpl(filters);
        this.dbCollection = dbCollection;
    }

    @Override
    public void addOption(int $0) {
        filterChain.dbCollection_addOption(this.dbCollection, $0);
    }

    @Override
    public AggregationOutput aggregate(DBObject $0, DBObject... $1) {
        return filterChain.dbCollection_aggregate(this.dbCollection, $0, $1);
    }

    @Override
    public AggregationOutput aggregate(List $0) {
        return filterChain.dbCollection_aggregate(this.dbCollection, $0);
    }

    @Override
    public AggregationOutput aggregate(List $0, ReadPreference $1) {
        return filterChain.dbCollection_aggregate(this.dbCollection, $0, $1);
    }

    @Override
    public Cursor aggregate(List $0, AggregationOptions $1) {
        return filterChain.dbCollection_aggregate(this.dbCollection, $0, $1);
    }

    @Override
    public Cursor aggregate(List $0, AggregationOptions $1, ReadPreference $2) {
        return filterChain.dbCollection_aggregate(this.dbCollection, $0, $1, $2);
    }

    @Override
    public long count() {
        return filterChain.dbCollection_count(this.dbCollection);
    }

    @Override
    public long count(DBObject $0) {
        return filterChain.dbCollection_count(this.dbCollection, $0);
    }

    @Override
    public long count(DBObject $0, ReadPreference $1) {
        return filterChain.dbCollection_count(this.dbCollection, $0, $1);
    }

    @Override
    public long count(DBObject $0, DBCollectionCountOptions $1) {
        return filterChain.dbCollection_count(this.dbCollection, $0, $1);
    }

    @Override
    public void createIndex(DBObject $0) {
        filterChain.dbCollection_createIndex(this.dbCollection, $0);
    }

    @Override
    public void createIndex(DBObject $0, DBObject $1) {
        filterChain.dbCollection_createIndex(this.dbCollection, $0, $1);
    }

    @Override
    public void createIndex(DBObject $0, String $1) {
        filterChain.dbCollection_createIndex(this.dbCollection, $0, $1);
    }

    @Override
    public void createIndex(DBObject $0, String $1, boolean $2) {
        filterChain.dbCollection_createIndex(this.dbCollection, $0, $1, $2);
    }

    @Override
    public void createIndex(String $0) {
        filterChain.dbCollection_createIndex(this.dbCollection, $0);
    }

    @Override
    public List distinct(String $0) {
        return filterChain.dbCollection_distinct(this.dbCollection, $0);
    }

    @Override
    public List distinct(String $0, DBObject $1) {
        return filterChain.dbCollection_distinct(this.dbCollection, $0, $1);
    }

    @Override
    public List distinct(String $0, DBObject $1, ReadPreference $2) {
        return filterChain.dbCollection_distinct(this.dbCollection, $0, $1, $2);
    }

    @Override
    public List distinct(String $0, ReadPreference $1) {
        return filterChain.dbCollection_distinct(this.dbCollection, $0, $1);
    }

    @Override
    public List distinct(String $0, DBCollectionDistinctOptions $1) {
        return filterChain.dbCollection_distinct(this.dbCollection, $0, $1);
    }

    @Override
    public void drop() {
        filterChain.dbCollection_drop(this.dbCollection);
    }

    @Override
    public void dropIndex(DBObject $0) {
        filterChain.dbCollection_dropIndex(this.dbCollection, $0);
    }

    @Override
    public void dropIndex(String $0) {
        filterChain.dbCollection_dropIndex(this.dbCollection, $0);
    }

    @Override
    public void dropIndexes() {
        filterChain.dbCollection_dropIndexes(this.dbCollection);
    }

    @Override
    public void dropIndexes(String $0) {
        filterChain.dbCollection_dropIndexes(this.dbCollection, $0);
    }

    @Override
    public CommandResult explainAggregate(List $0, AggregationOptions $1) {
        return filterChain.dbCollection_explainAggregate(this.dbCollection, $0, $1);
    }

    @Override
    public DBCursor find() {
        return filterChain.dbCollection_find(this.dbCollection);
    }

    @Override
    public DBCursor find(DBObject $0) {
        return filterChain.dbCollection_find(this.dbCollection, $0);
    }

    @Override
    public DBCursor find(DBObject $0, DBObject $1) {
        return filterChain.dbCollection_find(this.dbCollection, $0, $1);
    }

    @Override
    public DBCursor find(DBObject $0, DBObject $1, int $2, int $3) {
        return filterChain.dbCollection_find(this.dbCollection, $0, $1, $2, $3);
    }

    @Override
    public DBCursor find(DBObject $0, DBObject $1, int $2, int $3, int $4) {
        return filterChain.dbCollection_find(this.dbCollection, $0, $1, $2, $3, $4);
    }

    @Override
    public DBCursor find(DBObject $0, DBCollectionFindOptions $1) {
        return filterChain.dbCollection_find(this.dbCollection, $0, $1);
    }

    @Override
    public DBObject findAndModify(DBObject $0, DBObject $1) {
        return filterChain.dbCollection_findAndModify(this.dbCollection, $0, $1);
    }

    @Override
    public DBObject findAndModify(DBObject $0, DBObject $1, DBObject $2) {
        return filterChain.dbCollection_findAndModify(this.dbCollection, $0, $1, $2);
    }

    @Override
    public DBObject findAndModify(DBObject $0, DBObject $1, DBObject $2, boolean $3, DBObject $4, boolean $5, boolean $6) {
        return filterChain.dbCollection_findAndModify(this.dbCollection, $0, $1, $2, $3, $4, $5, $6);
    }

    @Override
    public DBObject findAndModify(DBObject $0, DBObject $1, DBObject $2, boolean $3, DBObject $4, boolean $5, boolean $6, boolean $7, long $8, TimeUnit $9) {
        return filterChain.dbCollection_findAndModify(this.dbCollection, $0, $1, $2, $3, $4, $5, $6, $7, $8, $9);
    }

    @Override
    public DBObject findAndModify(DBObject $0, DBObject $1, DBObject $2, boolean $3, DBObject $4, boolean $5, boolean $6, boolean $7, long $8, TimeUnit $9, WriteConcern $10) {
        return filterChain.dbCollection_findAndModify(this.dbCollection, $0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10);
    }

    @Override
    public DBObject findAndModify(DBObject $0, DBObject $1, DBObject $2, boolean $3, DBObject $4, boolean $5, boolean $6, WriteConcern $7) {
        return filterChain.dbCollection_findAndModify(this.dbCollection, $0, $1, $2, $3, $4, $5, $6, $7);
    }

    @Override
    public DBObject findAndModify(DBObject $0, DBObject $1, DBObject $2, boolean $3, DBObject $4, boolean $5, boolean $6, long $7, TimeUnit $8) {
        return filterChain.dbCollection_findAndModify(this.dbCollection, $0, $1, $2, $3, $4, $5, $6, $7, $8);
    }

    @Override
    public DBObject findAndModify(DBObject $0, DBObject $1, DBObject $2, boolean $3, DBObject $4, boolean $5, boolean $6, long $7, TimeUnit $8, WriteConcern $9) {
        return filterChain.dbCollection_findAndModify(this.dbCollection, $0, $1, $2, $3, $4, $5, $6, $7, $8, $9);
    }

    @Override
    public DBObject findAndModify(DBObject $0, DBCollectionFindAndModifyOptions $1) {
        return filterChain.dbCollection_findAndModify(this.dbCollection, $0, $1);
    }

    @Override
    public DBObject findAndRemove(DBObject $0) {
        return filterChain.dbCollection_findAndRemove(this.dbCollection, $0);
    }

    @Override
    public DBObject findOne() {
        return filterChain.dbCollection_findOne(this.dbCollection);
    }

    @Override
    public DBObject findOne(DBObject $0) {
        return filterChain.dbCollection_findOne(this.dbCollection, $0);
    }

    @Override
    public DBObject findOne(DBObject $0, DBObject $1) {
        return filterChain.dbCollection_findOne(this.dbCollection, $0, $1);
    }

    @Override
    public DBObject findOne(DBObject $0, DBObject $1, DBObject $2) {
        return filterChain.dbCollection_findOne(this.dbCollection, $0, $1, $2);
    }

    @Override
    public DBObject findOne(DBObject $0, DBObject $1, DBObject $2, ReadPreference $3) {
        return filterChain.dbCollection_findOne(this.dbCollection, $0, $1, $2, $3);
    }

    @Override
    public DBObject findOne(DBObject $0, DBObject $1, ReadPreference $2) {
        return filterChain.dbCollection_findOne(this.dbCollection, $0, $1, $2);
    }

    @Override
    public DBObject findOne(DBObject $0, DBCollectionFindOptions $1) {
        return filterChain.dbCollection_findOne(this.dbCollection, $0, $1);
    }

    @Override
    public DBObject findOne(Object $0) {
        return filterChain.dbCollection_findOne(this.dbCollection, $0);
    }

    @Override
    public DBObject findOne(Object $0, DBObject $1) {
        return filterChain.dbCollection_findOne(this.dbCollection, $0, $1);
    }

    @Override
    public DBCollection getCollection(String $0) {
        return filterChain.dbCollection_getCollection(this.dbCollection, $0);
    }

    @Override
    public long getCount() {
        return filterChain.dbCollection_getCount(this.dbCollection);
    }

    @Override
    public long getCount(DBObject $0) {
        return filterChain.dbCollection_getCount(this.dbCollection, $0);
    }

    @Override
    public long getCount(DBObject $0, DBObject $1) {
        return filterChain.dbCollection_getCount(this.dbCollection, $0, $1);
    }

    @Override
    public long getCount(DBObject $0, DBObject $1, ReadPreference $2) {
        return filterChain.dbCollection_getCount(this.dbCollection, $0, $1, $2);
    }

    @Override
    public long getCount(DBObject $0, DBObject $1, long $2, long $3) {
        return filterChain.dbCollection_getCount(this.dbCollection, $0, $1, $2, $3);
    }

    @Override
    public long getCount(DBObject $0, DBObject $1, long $2, long $3, ReadPreference $4) {
        return filterChain.dbCollection_getCount(this.dbCollection, $0, $1, $2, $3, $4);
    }

    @Override
    public long getCount(DBObject $0, DBCollectionCountOptions $1) {
        return filterChain.dbCollection_getCount(this.dbCollection, $0, $1);
    }

    @Override
    public long getCount(ReadPreference $0) {
        return filterChain.dbCollection_getCount(this.dbCollection, $0);
    }

    @Override
    public DB getDB() {
        return filterChain.dbCollection_getDB(this.dbCollection);
    }

    @Override
    public DBDecoderFactory getDBDecoderFactory() {
        return filterChain.dbCollection_getDBDecoderFactory(this.dbCollection);
    }

    @Override
    public DBEncoderFactory getDBEncoderFactory() {
        return filterChain.dbCollection_getDBEncoderFactory(this.dbCollection);
    }

    @Override
    public String getFullName() {
        return filterChain.dbCollection_getFullName(this.dbCollection);
    }

    @Override
    public List getHintFields() {
        return filterChain.dbCollection_getHintFields(this.dbCollection);
    }

    @Override
    public List getIndexInfo() {
        return filterChain.dbCollection_getIndexInfo(this.dbCollection);
    }

    @Override
    public String getName() {
        return filterChain.dbCollection_getName(this.dbCollection);
    }

    @Override
    public Class getObjectClass() {
        return filterChain.dbCollection_getObjectClass(this.dbCollection);
    }

    @Override
    public int getOptions() {
        return filterChain.dbCollection_getOptions(this.dbCollection);
    }

    @Override
    public ReadConcern getReadConcern() {
        return filterChain.dbCollection_getReadConcern(this.dbCollection);
    }

    @Override
    public ReadPreference getReadPreference() {
        return filterChain.dbCollection_getReadPreference(this.dbCollection);
    }

    @Override
    public CommandResult getStats() {
        return filterChain.dbCollection_getStats(this.dbCollection);
    }

    @Override
    public WriteConcern getWriteConcern() {
        return filterChain.dbCollection_getWriteConcern(this.dbCollection);
    }

    @Override
    public DBObject group(DBObject $0, DBObject $1, DBObject $2, String $3) {
        return filterChain.dbCollection_group(this.dbCollection, $0, $1, $2, $3);
    }

    @Override
    public DBObject group(DBObject $0, DBObject $1, DBObject $2, String $3, String $4) {
        return filterChain.dbCollection_group(this.dbCollection, $0, $1, $2, $3, $4);
    }

    @Override
    public DBObject group(DBObject $0, DBObject $1, DBObject $2, String $3, String $4, ReadPreference $5) {
        return filterChain.dbCollection_group(this.dbCollection, $0, $1, $2, $3, $4, $5);
    }

    @Override
    public DBObject group(GroupCommand $0) {
        return filterChain.dbCollection_group(this.dbCollection, $0);
    }

    @Override
    public DBObject group(GroupCommand $0, ReadPreference $1) {
        return filterChain.dbCollection_group(this.dbCollection, $0, $1);
    }

    @Override
    public BulkWriteOperation initializeOrderedBulkOperation() {
        return filterChain.dbCollection_initializeOrderedBulkOperation(this.dbCollection);
    }

    @Override
    public BulkWriteOperation initializeUnorderedBulkOperation() {
        return filterChain.dbCollection_initializeUnorderedBulkOperation(this.dbCollection);
    }

    @Override
    public WriteResult insert(DBObject $0, WriteConcern $1) {
        return filterChain.dbCollection_insert(this.dbCollection, $0, $1);
    }

    @Override
    public WriteResult insert(DBObject... $0) {
        return filterChain.dbCollection_insert(this.dbCollection, $0);
    }

    @Override
    public WriteResult insert(DBObject[] $0, WriteConcern $1) {
        return filterChain.dbCollection_insert(this.dbCollection, $0, $1);
    }

    @Override
    public WriteResult insert(DBObject[] $0, WriteConcern $1, DBEncoder $2) {
        return filterChain.dbCollection_insert(this.dbCollection, $0, $1, $2);
    }

    @Override
    public WriteResult insert(WriteConcern $0, DBObject... $1) {
        return filterChain.dbCollection_insert(this.dbCollection, $0, $1);
    }

    @Override
    public WriteResult insert(List $0) {
        return filterChain.dbCollection_insert(this.dbCollection, $0);
    }

    @Override
    public WriteResult insert(List $0, InsertOptions $1) {
        return filterChain.dbCollection_insert(this.dbCollection, $0, $1);
    }

    @Override
    public WriteResult insert(List $0, WriteConcern $1) {
        return filterChain.dbCollection_insert(this.dbCollection, $0, $1);
    }

    @Override
    public WriteResult insert(List $0, WriteConcern $1, DBEncoder $2) {
        return filterChain.dbCollection_insert(this.dbCollection, $0, $1, $2);
    }

    @Override
    public boolean isCapped() {
        return filterChain.dbCollection_isCapped(this.dbCollection);
    }

    @Override
    public MapReduceOutput mapReduce(MapReduceCommand $0) {
        return filterChain.dbCollection_mapReduce(this.dbCollection, $0);
    }

    @Override
    public MapReduceOutput mapReduce(String $0, String $1, String $2, DBObject $3) {
        return filterChain.dbCollection_mapReduce(this.dbCollection, $0, $1, $2, $3);
    }

    @Override
    public MapReduceOutput mapReduce(String $0, String $1, String $2, OutputType $3, DBObject $4) {
        return filterChain.dbCollection_mapReduce(this.dbCollection, $0, $1, $2, $3, $4);
    }

    @Override
    public MapReduceOutput mapReduce(String $0, String $1, String $2, OutputType $3, DBObject $4, ReadPreference $5) {
        return filterChain.dbCollection_mapReduce(this.dbCollection, $0, $1, $2, $3, $4, $5);
    }

    @Override
    public List parallelScan(ParallelScanOptions $0) {
        return filterChain.dbCollection_parallelScan(this.dbCollection, $0);
    }

    @Override
    public WriteResult remove(DBObject $0) {
        return filterChain.dbCollection_remove(this.dbCollection, $0);
    }

    @Override
    public WriteResult remove(DBObject $0, WriteConcern $1) {
        return filterChain.dbCollection_remove(this.dbCollection, $0, $1);
    }

    @Override
    public WriteResult remove(DBObject $0, WriteConcern $1, DBEncoder $2) {
        return filterChain.dbCollection_remove(this.dbCollection, $0, $1, $2);
    }

    @Override
    public WriteResult remove(DBObject $0, DBCollectionRemoveOptions $1) {
        return filterChain.dbCollection_remove(this.dbCollection, $0, $1);
    }

    @Override
    public DBCollection rename(String $0) {
        return filterChain.dbCollection_rename(this.dbCollection, $0);
    }

    @Override
    public DBCollection rename(String $0, boolean $1) {
        return filterChain.dbCollection_rename(this.dbCollection, $0, $1);
    }

    @Override
    public void resetOptions() {
        filterChain.dbCollection_resetOptions(this.dbCollection);
    }

    @Override
    public WriteResult save(DBObject $0) {
        return filterChain.dbCollection_save(this.dbCollection, $0);
    }

    @Override
    public WriteResult save(DBObject $0, WriteConcern $1) {
        return filterChain.dbCollection_save(this.dbCollection, $0, $1);
    }

    @Override
    public void setDBDecoderFactory(DBDecoderFactory $0) {
        filterChain.dbCollection_setDBDecoderFactory(this.dbCollection, $0);
    }

    @Override
    public void setDBEncoderFactory(DBEncoderFactory $0) {
        filterChain.dbCollection_setDBEncoderFactory(this.dbCollection, $0);
    }

    @Override
    public void setHintFields(List $0) {
        filterChain.dbCollection_setHintFields(this.dbCollection, $0);
    }

    @Override
    public void setInternalClass(String $0, Class $1) {
        filterChain.dbCollection_setInternalClass(this.dbCollection, $0, $1);
    }

    @Override
    public void setObjectClass(Class $0) {
        filterChain.dbCollection_setObjectClass(this.dbCollection, $0);
    }

    @Override
    public void setOptions(int $0) {
        filterChain.dbCollection_setOptions(this.dbCollection, $0);
    }

    @Override
    public void setReadConcern(ReadConcern $0) {
        filterChain.dbCollection_setReadConcern(this.dbCollection, $0);
    }

    @Override
    public void setReadPreference(ReadPreference $0) {
        filterChain.dbCollection_setReadPreference(this.dbCollection, $0);
    }

    @Override
    public void setWriteConcern(WriteConcern $0) {
        filterChain.dbCollection_setWriteConcern(this.dbCollection, $0);
    }

    @Override
    public void slaveOk() {
        filterChain.dbCollection_slaveOk(this.dbCollection);
    }

    @Override
    public String toString() {
        return filterChain.dbCollection_toString(this.dbCollection);
    }

    @Override
    public WriteResult update(DBObject $0, DBObject $1) {
        return filterChain.dbCollection_update(this.dbCollection, $0, $1);
    }

    @Override
    public WriteResult update(DBObject $0, DBObject $1, boolean $2, boolean $3) {
        return filterChain.dbCollection_update(this.dbCollection, $0, $1, $2, $3);
    }

    @Override
    public WriteResult update(DBObject $0, DBObject $1, boolean $2, boolean $3, WriteConcern $4) {
        return filterChain.dbCollection_update(this.dbCollection, $0, $1, $2, $3, $4);
    }

    @Override
    public WriteResult update(DBObject $0, DBObject $1, boolean $2, boolean $3, WriteConcern $4, DBEncoder $5) {
        return filterChain.dbCollection_update(this.dbCollection, $0, $1, $2, $3, $4, $5);
    }

    @Override
    public WriteResult update(DBObject $0, DBObject $1, boolean $2, boolean $3, WriteConcern $4, Boolean $5, DBEncoder $6) {
        return filterChain.dbCollection_update(this.dbCollection, $0, $1, $2, $3, $4, $5, $6);
    }

    @Override
    public WriteResult update(DBObject $0, DBObject $1, DBCollectionUpdateOptions $2) {
        return filterChain.dbCollection_update(this.dbCollection, $0, $1, $2);
    }

    @Override
    public WriteResult updateMulti(DBObject $0, DBObject $1) {
        return filterChain.dbCollection_updateMulti(this.dbCollection, $0, $1);
    }

}